package com.voice.core.connection.impl;

import com.voice.core.connection.Connection;
import com.voice.core.connection.ConnectionListener;
import com.voice.core.connection.ConnectionStatus;
import com.voice.core.connection.callback.StreamListener;
import com.voice.core.connection.entity.Stream;

import java.util.HashMap;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class AbstractConnection implements Connection {

    private HashMap<Integer, Stream> streamHashMap = new HashMap<>();
    private ConnectionListener connectionListener;
    private ConnectionStatus status;
    private AtomicInteger currentStreamId ;
    private volatile StreamListener defaultStreamListener;

    public AbstractConnection(int currentStreamId) {
        this.currentStreamId=new AtomicInteger(currentStreamId);
    }

    @Override
    public void setConnectionListener(ConnectionListener connectionListener) {
        this.connectionListener = connectionListener;
        if (connectionListener != null&&status!=null) connectionListener.onStatusChange(status, this);
    }

    @Override
    public void removeConnectListener() {
        this.connectionListener = null;
    }

    @Override
    public void onConnectionClosed() {
        this.setStatus(ConnectionStatus.CLOSED);
    }

    @Override
    public void setStatus(ConnectionStatus status) {
        if (this.connectionListener != null) {
            this.connectionListener.onStatusChange(status, this);
        }
        this.status = status;
    }

    @Override
    public ConnectionStatus getStatus() {
        return status;
    }


    public  void setStreamListener(int streamId, StreamListener streamListener){
        Stream  stream=new Stream(streamId,streamListener,this);
        streamHashMap.put(streamId,stream);
    }

    public Optional<StreamListener> streamListener(int streamId){
        if(!Optional.ofNullable(streamHashMap.get(streamId)).isPresent()) return Optional.empty();
        return Optional.ofNullable(streamHashMap.get(streamId).getStreamListener());
    }

    Stream stream(int streamId){
        return streamHashMap.get(streamId);
    }

    public  void removeStreamListener(int streamId){
        streamHashMap.remove(streamId);
    }

    public int incrementAndGetNextStreamId() {
        return currentStreamId.getAndAdd(2);
    }

    @Override
    public void setDefaultStreamListener(StreamListener listener) {
        this.defaultStreamListener = listener;
    }

    @Override
    public Optional<StreamListener> defaultStreamListener() {
        return Optional.ofNullable(defaultStreamListener);
    }

    public AtomicInteger getCurrentStreamId() {
        return currentStreamId;
    }
}
